#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/pixdesc.h>
#include <libavutil/channel_layout.h>
}

// 辅助函数：打印时间信息
void print_time_info(int64_t time_base, int64_t duration) {
    if (duration != AV_NOPTS_VALUE) {
        int hours, mins, secs, us;
        secs = duration / time_base;
        us = duration % time_base;
        mins = secs / 60;
        secs %= 60;
        hours = mins / 60;
        mins %= 60;
        std::cout << "时长: " << hours << ":" << mins << ":" << secs << "." << us << std::endl;
    } else {
        std::cout << "时长: 未知" << std::endl;
    }
}

// 辅助函数：打印比特率信息
void print_bitrate_info(int64_t bit_rate) {
    if (bit_rate > 0) {
        std::cout << "比特率: " << bit_rate / 1000 << " kbps" << std::endl;
    } else {
        std::cout << "比特率: 未知" << std::endl;
    }
}

int main() {
    // 创建日志文件
    std::ofstream logFile("debug.log");
    logFile << "程序开始运行..." << std::endl;
    
    try {
        // 设置控制台输出为UTF-8
        SetConsoleOutputCP(CP_UTF8);
        logFile << "设置控制台编码完成" << std::endl;
        
        std::cout << "开始初始化 FFmpeg..." << std::endl;
        logFile << "开始初始化 FFmpeg..." << std::endl;
        
        // 初始化 FFmpeg
        avformat_network_init();
        logFile << "FFmpeg 网络初始化完成" << std::endl;

        // 打开输入流
        AVFormatContext* formatContext = nullptr;
        const char* url = "rtsp://10.0.11.6:554/channel=0,stream=0";
        
        std::cout << "正在连接到: " << url << std::endl;
        logFile << "正在连接到: " << url << std::endl;
        
        // 设置超时选项
        AVDictionary* options = nullptr;
        av_dict_set(&options, "rtsp_transport", "tcp", 0);
        av_dict_set(&options, "stimeout", "5000000", 0);  // 5秒超时
        logFile << "设置超时选项完成" << std::endl;

        int ret = avformat_open_input(&formatContext, url, nullptr, &options);
        if (ret < 0) {
            char errbuf[AV_ERROR_MAX_STRING_SIZE];
            av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
            std::cerr << "无法打开输入流: " << errbuf << std::endl;
            std::cerr << "错误代码: " << ret << std::endl;
            logFile << "无法打开输入流: " << errbuf << std::endl;
            logFile << "错误代码: " << ret << std::endl;
            return -1;
        }

        logFile << "成功打开输入流" << std::endl;
        std::cout << "成功打开输入流，正在获取流信息..." << std::endl;

        // 获取流信息
        ret = avformat_find_stream_info(formatContext, nullptr);
        if (ret < 0) {
            char errbuf[AV_ERROR_MAX_STRING_SIZE];
            av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
            std::cerr << "无法获取流信息: " << errbuf << std::endl;
            std::cerr << "错误代码: " << ret << std::endl;
            logFile << "无法获取流信息: " << errbuf << std::endl;
            logFile << "错误代码: " << ret << std::endl;
            avformat_close_input(&formatContext);
            return -1;
        }

        logFile << "成功获取流信息" << std::endl;

        // 打印容器格式信息
        std::cout << "\n=== 容器格式信息 ===" << std::endl;
        std::cout << "格式名称: " << formatContext->iformat->name << std::endl;
        std::cout << "格式长名称: " << formatContext->iformat->long_name << std::endl;
        print_time_info(AV_TIME_BASE, formatContext->duration);
        print_bitrate_info(formatContext->bit_rate);

        // 打印元数据信息
        if (formatContext->metadata) {
            std::cout << "\n=== 元数据信息 ===" << std::endl;
            AVDictionaryEntry* tag = nullptr;
            while ((tag = av_dict_get(formatContext->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
                std::cout << tag->key << ": " << tag->value << std::endl;
            }
        }

        // 遍历所有流
        for (unsigned int i = 0; i < formatContext->nb_streams; i++) {
            AVStream* stream = formatContext->streams[i];
            AVCodecParameters* codecParams = stream->codecpar;
            
            std::cout << "\n=== 流 #" << i << " 信息 ===" << std::endl;
            std::cout << "流类型: " << av_get_media_type_string(codecParams->codec_type) << std::endl;
            std::cout << "编码器: " << avcodec_get_name(codecParams->codec_id) << std::endl;
            std::cout << "编码器长名称: " << avcodec_get_name(codecParams->codec_id) << std::endl;
            
            if (codecParams->codec_type == AVMEDIA_TYPE_VIDEO) {
                std::cout << "\n--- 视频信息 ---" << std::endl;
                std::cout << "分辨率: " << codecParams->width << "x" << codecParams->height << std::endl;
                std::cout << "帧率: " << av_q2d(stream->r_frame_rate) << " fps" << std::endl;
                std::cout << "平均帧率: " << av_q2d(stream->avg_frame_rate) << " fps" << std::endl;
                std::cout << "色彩空间: " << av_get_pix_fmt_name((AVPixelFormat)codecParams->format) << std::endl;
                std::cout << "色彩范围: " << av_color_range_name(codecParams->color_range) << std::endl;
                std::cout << "色彩空间: " << av_color_space_name(codecParams->color_space) << std::endl;
                std::cout << "色彩传输特性: " << av_color_transfer_name(codecParams->color_trc) << std::endl;
                std::cout << "色彩原色: " << av_color_primaries_name(codecParams->color_primaries) << std::endl;
                print_bitrate_info(codecParams->bit_rate);
                
                // 打印视频流元数据
                if (stream->metadata) {
                    std::cout << "\n--- 视频流元数据 ---" << std::endl;
                    AVDictionaryEntry* tag = nullptr;
                    while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
                        std::cout << tag->key << ": " << tag->value << std::endl;
                    }
                }
            }
            else if (codecParams->codec_type == AVMEDIA_TYPE_AUDIO) {
                std::cout << "\n--- 音频信息 ---" << std::endl;
                std::cout << "采样率: " << codecParams->sample_rate << " Hz" << std::endl;
                std::cout << "声道数: " << codecParams->ch_layout.nb_channels << std::endl;
                std::cout << "声道布局: " << codecParams->ch_layout.nb_channels << " 声道" << std::endl;
                std::cout << "采样格式: " << av_get_sample_fmt_name((AVSampleFormat)codecParams->format) << std::endl;
                std::cout << "每采样位数: " << av_get_bits_per_sample(codecParams->codec_id) << " bits" << std::endl;
                print_bitrate_info(codecParams->bit_rate);
                
                // 打印音频流元数据
                if (stream->metadata) {
                    std::cout << "\n--- 音频流元数据 ---" << std::endl;
                    AVDictionaryEntry* tag = nullptr;
                    while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
                        std::cout << tag->key << ": " << tag->value << std::endl;
                    }
                }
            }
            else if (codecParams->codec_type == AVMEDIA_TYPE_SUBTITLE) {
                std::cout << "\n--- 字幕信息 ---" << std::endl;
                std::cout << "字幕编码: " << avcodec_get_name(codecParams->codec_id) << std::endl;
                
                // 打印字幕流元数据
                if (stream->metadata) {
                    std::cout << "\n--- 字幕流元数据 ---" << std::endl;
                    AVDictionaryEntry* tag = nullptr;
                    while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
                        std::cout << tag->key << ": " << tag->value << std::endl;
                    }
                }
            }
        }

        // 清理资源
        avformat_close_input(&formatContext);
        avformat_network_deinit();
        logFile << "程序正常结束" << std::endl;

    } catch (const std::exception& e) {
        logFile << "发生异常: " << e.what() << std::endl;
        return -1;
    } catch (...) {
        logFile << "发生未知异常" << std::endl;
        return -1;
    }

    logFile.close();
    return 0;
} 